package com.ruicar.afs.cloud.manage.workflow.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.security.service.AfsUser;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.manage.common.entity.ManageApprovalRecord;
import com.ruicar.afs.cloud.manage.common.service.ManageApprovalRecordService;
import com.ruicar.afs.cloud.manage.workflow.entity.WorkTaskAssignInfo;
import com.ruicar.afs.cloud.manage.workflow.enums.NormalSubmitEnum;
import com.ruicar.afs.cloud.manage.workflow.response.WorkflowResponse;
import com.ruicar.afs.cloud.manage.workflow.service.WorkTaskAssignInfoService;
import com.ruicar.afs.cloud.manage.workflow.service.WorkflowSubmitService;
import com.ruicar.afs.cloud.manage.workflow.vo.TaskSubmitVO;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.WorkFlowResponse;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.QueryFLowCmdRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.TaskSubmitRequest;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.response.FlowCmdBean;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author xudongdong
 * @Description 常规流程提交
 */
@Service
@AllArgsConstructor
@Slf4j
public class NormalSubmitServiceImpl implements WorkflowSubmitService {
    private final WorkflowService workflowService;
    private final WorkTaskAssignInfoService workTaskAssignInfoService;
    private final ManageApprovalRecordService manageApprovalRecordService;

    @Override
    public WorkflowResponse submit(TaskSubmitVO submitVO) {
        AfsUser user = SecurityUtils.getUser();
        ManageApprovalRecord record = JSON.toJavaObject(submitVO.getBizData(), ManageApprovalRecord.class);
        record.setId(null);
        record.setBizDataId(String.valueOf(submitVO.getBizData().get("id")));
        submitVO.setWorkTaskAssignInfo(workTaskAssignInfoService.getOne(Wrappers.<WorkTaskAssignInfo>lambdaQuery()
                .eq(WorkTaskAssignInfo::getBizDataId, record.getBizDataId())
                .and(wraper -> wraper
                        .eq(WorkTaskAssignInfo::getUserName, user.getUsername())
                        .or()
                        .in(WorkTaskAssignInfo::getUserName, user.getRoleCodeList())
                    )
                )
        );
        NormalSubmitEnum submitEnum = (NormalSubmitEnum) AfsEnumUtil.getEnum(submitVO.getApprovalOperating(), NormalSubmitEnum.class);
        switch (submitEnum) {
            case SUGGEST_CHECK_FINAL:
                sumbit(submitVO);
                break;
            case SUGGEST_REJECT_FINAL:
                rejectFinal(submitVO);
                break;
            case SEND_BACK:
                sendBack(submitVO);
                break;
            default:
                log.info("审批建议不存在:{}", submitEnum);
        }
        return WorkflowResponse.empty();
    }

    /**
     * @Description 退回
     */
    public void sendBack(TaskSubmitVO submitVO) {
        String cmdName = AfsEnumUtil.desc(NormalSubmitEnum.SEND_BACK);
        saveRecord(submitVO, cmdName);
        pushWorkflow(cmdName, submitVO.getWorkTaskAssignInfo(), submitVO.getBizData());
    }

    /**
     * @Description 核准
     */
    public void sumbit(TaskSubmitVO submitVO) {
        String cmdName = AfsEnumUtil.desc(NormalSubmitEnum.SUGGEST_CHECK_FINAL);
        saveRecord(submitVO, cmdName);
        pushWorkflow(cmdName, submitVO.getWorkTaskAssignInfo(), submitVO.getBizData());
    }

    /**
     * @Description 拒绝
     */
    public void rejectFinal(TaskSubmitVO submitVO) {
        String cmdName = AfsEnumUtil.desc(NormalSubmitEnum.SUGGEST_REJECT_FINAL);
        saveRecord(submitVO, cmdName);
        pushWorkflow(cmdName, submitVO.getWorkTaskAssignInfo(), submitVO.getBizData());
    }

    /**
     * @Description 提交，工作流推进
     */
    public void pushWorkflow(String cmdName, WorkTaskAssignInfo workTaskAssignInfo, JSONObject bizData) {
        QueryFLowCmdRequest request = new QueryFLowCmdRequest();
        request.setFlowInstanceId(workTaskAssignInfo.getFlowInstanceId());
        WorkFlowResponse<List<FlowCmdBean>> list = workflowService.queryFlowCmd(request);
        for (FlowCmdBean cmdDatum : list.getAfsData()) {
            if (cmdDatum.getCmdDis().equals(cmdName)) {
                TaskSubmitRequest taskSubmitRequest = new TaskSubmitRequest();
                taskSubmitRequest.setGwtUserId(workTaskAssignInfo.getGwtUserId());
                taskSubmitRequest.setAfsFlowKey(AfsEnumUtil.key(workTaskAssignInfo.getAfsFlowKey()));
                taskSubmitRequest.setBizDataId(workTaskAssignInfo.getBizDataId());
                taskSubmitRequest.setCmdId(cmdDatum.getId());
                workflowService.taskSubmit(taskSubmitRequest, bizData);
                break;
            }
        }
    }

    /**
     * @Description 保存日志
     */
    @Override
    public void saveRecord(TaskSubmitVO submitVO, String cmdName) {
        ManageApprovalRecord record = JSON.toJavaObject(submitVO.getBizData(), ManageApprovalRecord.class);
        record.setId(null);
        record.setCreateBy(null);
        record.setCreateTime(null);
        record.setUpdateBy(null);
        record.setUpdateTime(null);
        record.setBizDataId(String.valueOf(submitVO.getBizData().get("id")));
        record.setApprovalOpinion(cmdName);
        record.setRemarks(submitVO.getApprovalOpinion());
        record.setReasonType(submitVO.getReasonType());
        WorkTaskAssignInfo workTaskAssignInfo = submitVO.getWorkTaskAssignInfo();
        AfsUser user = SecurityUtils.getUser();
        // 删除当前任务
        workTaskAssignInfoService.remove(Wrappers.<WorkTaskAssignInfo>lambdaQuery()
                .eq(WorkTaskAssignInfo::getBizDataId, record.getBizDataId()));
        // 保存流程操作日志
        record.setProcessPerson(user.getUserRealName());
        if (workTaskAssignInfo != null) {
            record.setProcessNode(workTaskAssignInfo.getTaskNodeId());
            record.setNodeName(workTaskAssignInfo.getTaskName());
        } else {
            record.setNodeName("开始节点");
        }
        manageApprovalRecordService.save(record);
    }
}
